// =((^3^))= EMMCC h1

#ifndef _EMMCC_LEXER_H_
#define _EMMCC_LEXER_H_

#include <vector>
#include <set>
#include <string>
#include <functional>

enum class TokenType {
// =((^3^))= EMMCC h1 end
    // 【!】根据tokens名称生成枚举内容
    EMMCC_INVALID, SYM_PAR_L, SYM_PAR_R, SYM_COM, KEY_VIBU, KEY_VIBD, INT, STRING, NAME
// =((^3^))= EMMCC h2
};

std::string TokenTypeToString(TokenType type);

class Token {
public:
    Token();
    std::string toString() const;

    TokenType type;
    std::string value;
    size_t row;
    size_t col;
    size_t priority; // 用于在多个长度相同的token中做选择
};

class LexerError {
public:
    LexerError();
    void set(const std::string& msg, size_t row_, size_t col_);
    std::string toString() const ;

    std::string message;
    size_t row;
    size_t col;
};

class Matcher;
class Lexer {
public:
    Lexer();
    ~Lexer();

    /**
     * 进行词法分析
     * @param content [IN] 要进行词法分析的内容
     * @param tokens [OUT] 分析后生成的tokens
     * @return 成功返回0，否则返回-1，失败后可通过getErrorInfo()获取错误信息
     */
    int parse(const std::string& content, std::vector<Token>& tokens);

    /**
     * 在parse()失败后，获取错误信息
     * 【注意】只有parse()失败后，错误信息才有意义
     */
    LexerError getErrorInfo() const;
private:
    /**
     * 获取某个字符对应的所有matcher
     */
    const std::vector<Matcher*>& getMatcher(char ch) const;
    std::vector<std::vector<Matcher*>> m_matcher_map;
    std::vector<Matcher*> m_matchers;
    LexerError m_error;
    std::set<char> m_blank_chars;
};

#endif//_EMMCC_LEXER_H_
// =((^3^))= EMMCC h2 end
